<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { Page } from '@vben/common-ui'
import { formatDateTime } from '@vben/utils'
import {
  ElButton,
  ElCard,
  ElForm,
  ElFormItem,
  ElInput,
  ElSelect,
  ElOption,
  ElDatePicker,
  ElTable,
  ElTableColumn,
  ElTag,
  ElPagination,
  ElDialog,
  ElInputNumber,
  ElMessage,
  ElMessageBox
} from 'element-plus'
import {
  getLoginLogsApi,
  getRecentLoginLogsApi,
  cleanLoginLogsByDaysApi,
  type LogApi
} from '#/api/core/log'
import type { PagedList } from '#/api/types'

// 状态管理
const loading = ref(false)
const dateRange = ref<string[]>([])
const searchForm = ref({
  userName: '',
  status: undefined as boolean | undefined,
  pageIndex: 1,
  pageSize: 10,
  startTime: '',
  endTime: '',
  orderBy: 'loginTime',
  isDescending: true
})

// 表格数据
const tableData = ref<PagedList<LogApi.LoginLogDto>>({
  items: [],
  totalCount: 0,
  pageIndex: 1,
  pageSize: 10,
  totalPages: 0,
  hasPreviousPage: false,
  hasNextPage: false
})

// 清理日志对话框
const cleanDialogVisible = ref(false)
const cleanForm = ref({
  days: 30
})

// 查询
const handleSearch = () => {
  searchForm.value.pageIndex = 1
  fetchData()
}

// 重置
const handleReset = () => {
  searchForm.value = {
    userName: '',
    status: undefined,
    pageIndex: 1,
    pageSize: 10,
    startTime: '',
    endTime: '',
    orderBy: 'loginTime',
    isDescending: true
  }
  dateRange.value = []
  fetchData()
}

// 获取最近一周日志
const handleGetRecent = async () => {
  loading.value = true
  try {
    const response = await getRecentLoginLogsApi()
    tableData.value = response
    ElMessage.success('获取最近一周日志成功')
  } catch (error) {
    ElMessage.error('获取最近一周日志失败')
  } finally {
    loading.value = false
  }
}

// 分页大小改变
const handleSizeChange = (val: number) => {
  searchForm.value.pageSize = val
  fetchData()
}

// 当前页改变
const handleCurrentChange = (val: number) => {
  searchForm.value.pageIndex = val
  fetchData()
}

// 打开清理日志对话框
const handleClean = () => {
  cleanDialogVisible.value = true
}

// 确认清理日志
const handleCleanConfirm = async () => {
  try {
    await ElMessageBox.confirm(
      `确定要清理 ${cleanForm.value.days} 天之前的日志吗？此操作不可恢复！`,
      '警告',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    loading.value = true
    const response = await cleanLoginLogsByDaysApi(cleanForm.value.days)
    ElMessage.success(`成功清理 ${response} 条日志`)
    cleanDialogVisible.value = false
    fetchData()
  } catch (error) {
    if (error instanceof Error) {
      ElMessage.error(error.message)
    }
  } finally {
    loading.value = false
  }
}

// 获取数据
const fetchData = async () => {
  loading.value = true
  try {
    const response = await getLoginLogsApi(searchForm.value)
    tableData.value = response
  } catch (error) {
    ElMessage.error('获取数据失败')
  } finally {
    loading.value = false
  }
}

// 监听日期范围变化
const handleDateRangeChange = (val: string[]) => {
  searchForm.value.startTime = val[0] || ''
  searchForm.value.endTime = val[1] || ''
}

// 页面加载时获取数据
onMounted(() => {
  fetchData()
})
</script>

<template>
  <Page title="登录日志" description="系统登录日志记录">
    <ElCard class="mb-4">
      <ElForm :model="searchForm" inline>
        <ElFormItem label="用户名">
          <ElInput
            v-model="searchForm.userName" style="width:240px"
            placeholder="请输入用户名"
            clearable
            @keyup.enter="handleSearch"
          />
        </ElFormItem>
        <ElFormItem label="登录状态">
          <ElSelect v-model="searchForm.status" placeholder="请选择" clearable style="width: 120px">
            <ElOption label="成功" :value="true" />
            <ElOption label="失败" :value="false" />
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="登录时间">
          <ElDatePicker
            v-model="dateRange"
            type="datetimerange"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            value-format="YYYY-MM-DD HH:mm:ss"
            @change="handleDateRangeChange"
          />
        </ElFormItem>
        <ElFormItem>
          <ElButton type="primary" @click="handleSearch">查询</ElButton>
          <ElButton @click="handleReset">重置</ElButton>
          <ElButton type="success" @click="handleGetRecent">最近一周</ElButton>
          <ElButton type="danger" @click="handleClean">清理日志</ElButton>
        </ElFormItem>
      </ElForm>
    </ElCard>

    <ElCard>
      <ElTable
        v-loading="loading"
        :data="tableData.items"
        border
        stripe
      >
        <ElTableColumn prop="userName" label="用户名" min-width="120" />
        <ElTableColumn prop="ipAddress" label="IP地址" min-width="120" />
        <ElTableColumn prop="browser" label="浏览器" min-width="120">
          <template #default="{ row }">
            {{ row.browser || '-' }}
          </template>
        </ElTableColumn>
        <ElTableColumn prop="os" label="操作系统" min-width="120">
          <template #default="{ row }">
            {{ row.os || '-' }}
          </template>
        </ElTableColumn>
        <ElTableColumn prop="status" label="状态" width="100">
          <template #default="{ row }">
            <ElTag :type="row.status ? 'success' : 'danger'">
              {{ row.status ? '成功' : '失败' }}
            </ElTag>
          </template>
        </ElTableColumn>
        <ElTableColumn prop="errorMessage" label="错误消息" min-width="200" show-overflow-tooltip>
          <template #default="{ row }">
            {{ row.errorMessage || row.message || '-' }}
          </template>
        </ElTableColumn>
        <ElTableColumn prop="loginTime" label="登录时间" min-width="180">
          <template #default="{ row }">
            {{ formatDateTime(row.loginTime) }}
          </template>
        </ElTableColumn>
        <ElTableColumn prop="level" label="日志级别" width="100">
          <template #default="{ row }">
            <ElTag :type="row.level === 'Information' ? 'success' : 'warning'">
              {{ row.level === 'Information' ? '信息' : '警告' }}
            </ElTag>
          </template>
        </ElTableColumn>
      </ElTable>

      <div class="mt-4 flex justify-end">
        <ElPagination
          v-model:current-page="searchForm.pageIndex"
          v-model:page-size="searchForm.pageSize"
          :total="tableData.totalCount"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </ElCard>

    <!-- 清理日志对话框 -->
    <ElDialog v-model="cleanDialogVisible" title="清理日志" width="400px">
      <ElForm :model="cleanForm" label-width="100px">
        <ElFormItem label="保留天数">
          <ElInputNumber v-model="cleanForm.days" :min="0" :max="365" />
        </ElFormItem>
      </ElForm>
      <template #footer>
        <span class="dialog-footer">
          <ElButton @click="cleanDialogVisible = false">取消</ElButton>
          <ElButton type="primary" @click="handleCleanConfirm">确定</ElButton>
        </span>
      </template>
    </ElDialog>
  </Page>
</template>
